﻿using GameProtocol;
using System;
using System.Collections.Generic;
using TEngine;
using UnityEngine;

namespace GameLogic
{
    public class ShipModule : BehaviourSingleton<ShipModule>
    {
        public static string ShipConfigDir = Application.dataPath + "/" + "AssetRaw/Configs/ShipConfigs/" ;
        int m_ShipIDCounter = 1;
        Dictionary<int, ShipControl> m_Ships = new Dictionary<int, ShipControl>();
        Dictionary<int, ShipDesignData> m_ShipDesigns = new Dictionary<int, ShipDesignData>();

        public Dictionary<int, ShipControl> Ships { get => m_Ships; set => m_Ships = value; }

        public void Init()
        {
            var designList = ConfigSystem.Instance.Tables.TbShipDesign.DataList;
            foreach(var i in designList)
            {
                var data = GameModule.Resource.LoadAsset<TextAsset>(i.DesignPath);
                var shipDesignData = ShipDesignData.Parser.ParseFrom(data.bytes);
                if(shipDesignData != null)
                {
                    m_ShipDesigns.Add(i.Id, shipDesignData);
                }
            }
        }

        ShipControl CreateShip(int shipID)
        {
            var shipCfg = ConfigSystem.Instance.Tables.TbShips.GetOrDefault(shipID);
            if (shipCfg == null)
            {
                Debug.LogError("ship creation failure: can't found id of ship : " + shipID);
                return null;
            }
            ShipControl shipControl = null;
            var shipObj = PoolManager.Instance.GetGameObjectCustomFlagName("Ship" + shipID, "Assets/AssetRaw/Ship/Prefabs/Ship.prefab");
            if (shipObj)
                shipControl = shipObj.GetComponent<ShipControl>();
            return shipControl;

        }


        public ShipDesignData GetShipDesign(int id)
        {
            return m_ShipDesigns?[id];
        }

        public Sprite GetShipSprite(int cfgID)
        {
            var shipCfg = ConfigSystem.Instance.Tables.TbShips.GetOrDefault(cfgID);
            Sprite retSprite = null;
            try
            {
                retSprite = GameModule.Resource.LoadAsset<Sprite>(shipCfg.SpritePath);
            }
            catch(Exception e) {
                Debug.LogError(e);
            }
            return retSprite;
        }
        public int GenerateShipID()
        {
            return m_ShipIDCounter++;
        }
        public ShipControl CreateShip(GameProtocol.ShipData shipData)
        {
            var shipC = CreateShip(shipData.CfgID);
            if (shipC == null)
            {
                Debug.LogError("ship creation failure: can't found id of ship : " + shipData.CfgID);
                return null;
            }
            if (m_Ships.ContainsKey(shipData.InstanceID))
                RemoveShip(shipData.InstanceID); 
            if (shipData.InstanceID == 0)
                shipData.InstanceID = GenerateShipID();
            shipC.Init(shipData);
            m_Ships.Add(shipData.InstanceID, shipC);
            if (m_ShipIDCounter < shipC.ShipData.Data.InstanceID)
                m_ShipIDCounter = shipC.ShipData.Data.InstanceID + 1;
            return shipC;
        }
        public ShipControl CreateShip(int shipCfgID, Vector3 position)
        {
            var shipC = CreateShip(shipCfgID);
            shipC.transform.position = position;
            shipC.Init(shipCfgID, m_ShipIDCounter);
            m_Ships.Add(m_ShipIDCounter, shipC);
            m_ShipIDCounter++;
            return shipC;
        }

        public void RemoveShip(int instanceID)
        {
            if (!m_Ships.ContainsKey(instanceID))
                return;
            m_Ships[instanceID].Clean();
            m_Ships[instanceID].gameObject.SetActive(false);
            PushShipToPool(m_Ships[instanceID].ShipData.Data.CfgID, m_Ships[instanceID]);
            m_Ships.Remove(instanceID);
        }
        public void PushShipToPool(int cfgID, ShipControl shipControl)
        {
            PoolManager.Instance.PushGameObject(shipControl.gameObject);
        }
        public void DoLogic()
        {
            foreach (var i in m_Ships)
            {
                i.Value.DoLogic();
            }
        }

        public ShipControl GetShip(int shipID)
        {
            if (!m_Ships.ContainsKey(shipID))
                return null;
            return m_Ships[shipID];
        }

        public void Clear()
        {
            foreach (var i in m_Ships)
            {
                i.Value.Clean();
                i.Value.gameObject.SetActive(false);
                PushShipToPool(i.Value.ShipData.Data.CfgID, i.Value);
            }
            m_Ships.Clear();
        }
    }
}
